from hashlib import sha1
from time import time, sleep, strftime, localtime, mktime, strptime
from random import random
from io import BytesIO
from base64 import b64encode
from PIL import Image
from json import loads
from exec import run_cmd
from cache import Cache
import uuid
import os
import datetime


def pidinfo(mode='all'):
    if mode == 'pid':
        return 'PID: %s' % os.getpid()
    if mode == 'ppid':
        return 'PID: %s, ParentID: %s' % (os.getpid(), os.getppid())
    return 'PID: %s, ParentID: %s, GroupID: %s' % (os.getpid(),
                                                   os.getppid(), os.getpgrp())

def randfloat(start, stop=None, bit=2):
    """
    获取随机浮点数
    """
    num = random() * 100000000
    if stop is None or stop == start:
        num = num % start
    else:
        num = num % (stop - start) + start
    return round(num, bit)

def loop(body, *args, **kwargs):
    """
    包装死循环
    """
    keys = kwargs.keys()
    quit = kwargs.pop('quit') if 'quit' in keys else True
    delay = kwargs.pop('delay') if 'delay' in keys else 0.1
    result = None
    while quit:
        result = body(*args, **kwargs)
        if result:
            break
        sleep(delay)

    return result

def retry(action, *args, **kwargs):
    """
    重试函数
    """
    keys = kwargs.keys()
    num = kwargs.pop('num') if 'num' in keys else 3
    delay = kwargs.pop('delay') if 'delay' in keys else (1, 2)
    delay = delay if isinstance(delay, tuple) else (delay, delay)
    tips = kwargs.pop('tips') if 'tips' in keys else None

    for i in range(num):
        result = action(*args, indx=i, **kwargs)
        if result:
            return result

        if callable(tips):
            tips(*args, indx=i, **kwargs)

        sleep(randfloat(*delay))
    return None

def redis():
    """
    缓存对象单例
    """
    if not hasattr(redis, 'connection'):
        redis.connection = Cache()
    return redis.connection

def get_mac_address():
    """
    获取本机MAC地址
    """
    mac=uuid.UUID(int = uuid.getnode()).hex[-12:]
    return ":".join([mac[e:e+2] for e in range(0,11,2)])

def get_center_md5():
    """
    获取本机唯一标识
    """
    return sha1(get_mac_address().encode()).hexdigest()

def make_verify_sign(data, signature=None, s='@#@#', key=''):
    """
    签名生成及验证
    """

    keys = list(data.keys())
    keys.sort()
    #  print('=====> SIGN: ', data)

    for x in keys:
        s += "%s=%s&" % (x, data[x])

    s += "@@@" + key

    sign_str = sha1(s.encode()).hexdigest()

    if signature is None:
        return sign_str

    return bool(sign_str == signature)

def get_timestamp(dt=None):
    """
    获取对应日期时间的时间戳
    """
    if dt is None:
        dt = now()
    return int(mktime(strptime(dt, "%Y-%m-%d %H:%M:%S")))

def now():
    return strftime('%Y-%m-%d %H:%M:%S', localtime())

def img2base64(img):
    if isinstance(img, str):
        img = Image.open(img)
    b = BytesIO()
    img.save(b, format='JPEG')
    return b64encode(b.getvalue()).decode()

def parse_param(args):
    """
    解析任务参数, JSON反序列化
    """
    if args is None:
        return None
    try:
        return loads(args)
    except:
        return args

def check_args(args, *keys):
    """
    检查任务参数
    """
    return any(args.get(x) in ['', None] for x in keys)

def day_to_sec(days=3):
    """
    天转化成秒, 从当前时间戳到几天后的0:0:0的秒数
    """
    tomrrow = datetime.date.today() + datetime.timedelta(days=days)
    return int(mktime(tomrrow.timetuple()) - time())

def cache_key(prefix, key, times=None):
    """
    获取缓存键名
    """
    times = int(times) if isinstance(times, str) else times
    return strftime(prefix + "_%Y%m%d_" + key, localtime(times))

def hwinfo():
    """
    获取硬件信息
    """
    hw = run_cmd("/works/fw id")[0][0].split("|")
    return {'name': hw[0], 'sn': hw[1], 'model': hw[2]}

